from django.db import models
from django.utils import timezone
from django.contrib.auth import get_user_model
from autoslug import AutoSlugField
from nanoid import generate
from slugify import slugify  # 替代 django.utils.text.slugify，支持中文


# 必须重新封装，不然会出错，所有直接调用函数的字段都会在makemigrations 时识别成属性而不是回调函数造成错误
def generate_id():
    return generate(size=21)


def py_slugify(value):
    return slugify(value)


class Article(models.Model):
    class ArticleStatus(models.TextChoices):
        DRAFT = 'draft', '草稿'
        PUBLISHED = 'published', '已发布'
        ARCHIVED = 'archived', '已归档'

    id = models.CharField(primary_key=True, max_length=21, default=generate_id, editable=False)
    title = models.CharField(max_length=200, verbose_name="标题")
    slug = AutoSlugField(slugify=py_slugify,
                         populate_from='title',
                         unique=True,
                         verbose_name="URL别名",
                         help_text="根据标题自动生成 URL Slug，可用于 SEO")
    content = models.TextField(verbose_name="正文内容")
    cover = models.ImageField(upload_to='articles/covers/', blank=True, null=True, verbose_name="封面图")
    is_public = models.BooleanField(default=True, verbose_name="是否公开")
    allow_comments = models.BooleanField(default=True, verbose_name="允许评论")
    summary = models.TextField(verbose_name="摘要", blank=True, default="")
    status = models.CharField(
        max_length=10,
        choices=ArticleStatus.choices,
        default=ArticleStatus.DRAFT,
        verbose_name="状态"
    )
    author = models.ForeignKey(get_user_model(),
                               on_delete=models.SET_NULL,
                               null=True,
                               verbose_name="作者",
                               related_name='articles')
    pub_time = models.DateTimeField(default=timezone.now, verbose_name="发布时间")
    update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    views = models.PositiveIntegerField(default=0, verbose_name="阅读数")
    is_top = models.BooleanField(default=False, verbose_name="是否置顶")
    is_show_toc = models.BooleanField(default=True, verbose_name="显示目录")  # 是否显示Table of Contents
    # 分类与标签
    category = models.ForeignKey("Category",
                                 on_delete=models.SET_NULL,
                                 null=True, blank=True,
                                 verbose_name="分类",
                                 related_name='articles')
    tags = models.ManyToManyField("Tag", blank=True, verbose_name="标签", related_name='articles')

    class Meta:
        db_table = 'blog_article'
        ordering = ['-is_top', '-pub_time']
        verbose_name = "文章"
        verbose_name_plural = "文章"

    def __str__(self):
        return self.title

    def increase_views(self):
        self.views = models.F('views') + 1
        self.save(update_fields=['views'])
        self.refresh_from_db(fields=['views'])  # 确保当前实例数据是最新的

    def get_absolute_url(self):
        from django.urls import reverse
        return reverse('article_detail', kwargs={'id': self.id, 'slug': self.slug})


class Category(models.Model):
    name = models.CharField(max_length=128, unique=True, verbose_name="分类名称")
    slug = AutoSlugField(slugify=py_slugify, populate_from='name', unique=True, verbose_name="URL别名")

    class Meta:
        db_table = 'blog_category'
        ordering = ['name']
        verbose_name = "分类"
        verbose_name_plural = "分类"

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        from django.urls import reverse
        return reverse('category_detail', kwargs={'id': self.id, 'slug': self.slug})


class Tag(models.Model):
    name = models.CharField(max_length=128, unique=True, verbose_name="标签名称")
    slug = AutoSlugField(slugify=py_slugify, populate_from='name', unique=True, verbose_name="URL别名")

    class Meta:
        db_table = 'blog_tag'
        ordering = ['name']
        verbose_name = "标签"
        verbose_name_plural = "标签"

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        from django.urls import reverse
        return reverse('tag_detail', kwargs={'id': self.id, 'slug': self.slug})
